home *** CD-ROM | disk | FTP | other *** search
- /*
- * WICONSETTER A companion utility to wIconify. wIconSetter allows
- * you to specify custom icons for windows ans screens
- * that normally use the default icons.
- *
- * wIconFileRead.c Reads the initialization file.
- *
- * Copyright 1990 by Davide P. Cervone, all rights reserved.
- * You may use this code, provided this copyright notice is kept intact.
- */
-
- #include "wIconFile.h"
-
- UWORD ImageData[MAXWORDS][MAXHEIGHT][MAXDEPTH];
- short MaxWidth,MaxHeight,MaxWords;
- UBYTE Plane0,Plane1;
- int ImageType;
- int IconFileOpen;
- short BitMapLine;
-
- static int NoMaskError; /* FALSE if a mask error was reported */
- static short ErrorCount; /* number of error messages so far */
-
- #define MAXERROR 8 /* maximum number of errors in a line */
-
-
- /*
- * Allowable HEX codes
- */
-
- static char *ExtHex = "0123456789abcdef)!@#$%^&*(ABCDEF";
-
- /*
- * The initialization file command keywords
- */
-
- static char *MainCommand[] =
- {
- "",
- "Program", /* Specifies Program name for this icon */
- "Screen", /* Specifies Screen name for this icon */
- "Window", /* SPecified window name for this icon */
- "Icon", /* Uses a DEFINEd icon, or read icon from file */
- "Image", /* Sets icon image */
- "Select", /* Sets icon select image */
- "Mask", /* Sets icon mask */
- "Flags", /* Sets the icon's flags */
- "Position", /* Sets initial position of icon */
- "Name", /* Sets icon's name when iconified */
- "Define", /* Defines an icon to be used more than once */
- };
- #define MAXMAINCOM COM_LAST
-
- /*
- * The commands for within an icon file (ICON: FROM commands)
- */
-
- static char *IconCommand[] =
- {
- "Image",
- "Select",
- "Mask",
- "Flags",
- "Position",
- "Name"
- };
- #define MAXICONCOM 5
-
- char **ComName = &MainCommand[0]; /* The current command set */
- static int ComOffset; /* Add this to get "real" command # */
- static int ComCount = MAXMAINCOM; /* Size of command array */
-
-
- /*
- * Icon Flags for FLAGS command
- */
-
- static struct Flag IconFlag[] =
- {
- {"NOICONIFY", WI_NOICONIFY}, /* Window can not be iconified */
- {"NOSAVEPOS", WI_NOSAVEPOS}, /* Position not saved when openned */
- {"NOCLOSE", WI_NOCLOSE}, /* CLOSE menu not available */
- {"NOORGANIZE", WI_NOORGANIZE}, /* Icon not affected by ORGANIZE */
- {"NOMOVE", WI_NOMOVE}, /* Icon can not be moved */
- {"LOCKED", WI_LOCKED}, /* Never change icon X,Y */
- {"NOMULTISELECT",WI_NOMULTISELECT}, /* No more than one icon selectable */
- {"CHANGEREFRESH",WI_CHANGEREFRESH}, /* Automatically change refresh type */
- {"AUTOICONIFY", WI_AUTOICONIFY}, /* Iconify window as it opens */
- };
- #define MAXICONFLAG 9
-
-
- /*
- * ReadCommand()
- *
- * If we're at the end of the line, read the next line.
- * Get the next word on the line.
- * If we have readed the end of the file, use COM_EOF
- * Otherwise, if the character following the next word is not ':'
- * then we have not found a command, so use COM_NONE,
- * Otherwise,
- * Look for the command in the current command table, and skip the ':'
- * Return the number of the command found.
- */
-
- int ReadCommand()
- {
- int Command = COM_UNKNOWN;
- short i;
-
- if (NextChar == '\n' || NextChar == 0) ReadNextLine();
- ReadNextWord();
- if (EndOfFile) Command = COM_EOF; else
- if (NextChar != ':') Command = COM_NONE;
- else
- {
- for (i=0; i<=ComCount && Command == COM_UNKNOWN; i++)
- if (WORDMATCH(ComName[i])) Command = i + ComOffset;
- SkipChar();
- }
- return(Command);
- }
-
-
- /*
- * ReadIconFlags()
- *
- * If the word is '+' or '|', then
- * If there were no previous flags specified, give an error
- * The next word is the flag name
- * Look through the flag names
- * If one of them matches,
- * Add the flag to the default flags and end the loop
- * If no flag found, give an error.
- */
-
- void ReadIconFlags(theFlags)
- ULONG *theFlags;
- {
- short i;
-
- if (Word[0] == '|' || Word[0] == '+')
- {
- if (*theFlags == 0)
- ShowError("Missing Icon Flag before '%c'",Word[0]);
- ReadNextWord();
- }
- for (i=0; i<MAXICONFLAG; i++)
- {
- if (WORDMATCH(IconFlag[i].Name))
- *theFlags |= IconFlag[i].Flag,
- i = MAXICONFLAG+1;
- }
- if (i == MAXICONFLAG) Expected("an Icon Flag");
- }
-
-
- /*
- * ReadInteger()
- *
- * Parse the next word as an integer.
- * If the word is an integer, return it, otherwise give an error.
- */
-
- void ReadInteger(i)
- int *i;
- {
- ReadNextInteger();
- if (sscanf(Word,"%d",i) != 1) Expected("an Integer value");
- }
-
-
- /*
- * ReadPosition()
- *
- * Start reading this data again.
- * If the word begins with a '(',
- * Skip it and read the x-position.
- * If the next char is a comma,
- * Skip it an read the y-position.
- * If the next character is a ')'
- * Skip it and save the position values if they are OK.
- * Otherwise, show an appropriate error.
- */
-
- void ReadPosition(x,y)
- WORD *x,*y;
- {
- int X = *x,
- Y = *y;
-
- Reread();
- if (NextChar == '(')
- {
- ReadNextChar(); ReadInteger(&X);
- if (NextChar == ',')
- {
- ReadNextChar(); ReadInteger(&Y);
- if (NextChar == ')')
- {
- ReadNextChar();
- if (X > 0 && Y > 0) *x = X, *y = Y;
- } else Expected(")"), NextChar = '\n';
- } else Expected(","), NextChar = '\n';
- } else Expected("an (x,y) position"), NextChar = '\n';
- }
-
-
- /*
- * CopyName()
- *
- * If we can allocate space for the name, copy it,
- * Otherwise, show an error.
- */
-
- void CopyName(s,Name)
- char **s;
- char *Name;
- {
- if (NEWCHAR(*s,strlen(Name))) strcpy(*s,Name);
- else ShowError("Can't get memory for character string");
- }
-
-
- /*
- * ReadName()
- *
- * Get the rest of the input line
- * If a name string already exists, free it
- * If the name is [ANY] or [NULL], set the special values,
- * Otherwise copy the new name to the name string.
- */
-
- void ReadName(name)
- char **name;
- {
- ReadFullLine();
- if (*name != NAME_NULL && *name != NAME_ANY) FREECHAR(*name);
- if (WORDMATCH("[ANY]")) *name = NAME_ANY; else
- if (WORDMATCH("[NULL]")) *name = NAME_NULL; else
- CopyName(name,Word);
- }
-
-
- /*
- * GetPen()
- *
- * Look for the given HEX digit in the extended HEX list.
- * If not found,
- * Give an error message and count the number of errors.
- * If more than the maximum allowed, skip the rest of the line.
- * If the image type is a MASK, and the pen is not 0 or 1,
- * If there were no previous errors of this type, give one.
- * Mark that the user was warned about mask pen types.
- * Reduce the pen number to 0 or 1.
- * Return the pen color.
- */
-
- static UBYTE GetPen(c)
- char c;
- {
- UBYTE Pen = 0;
- short i;
-
- for (i=0; i<32; i++) if (c == ExtHex[i]) Pen = i, i = 33;
- if (i == 32)
- {
- Expected("HEX Digit"); ErrorCount++;
- if (ErrorCount > MAXERROR)
- printf("Maximum errors exceeded - skipping rest of line\n"),
- SkipLine();
- }
- if (Pen > 1 && ImageType == COM_MASK)
- {
- if (NoMaskError) ShowError("Mask pixel values must be 0 or 1");
- NoMaskError = FALSE;
- Pen = Pen & 1;
- }
- return(Pen);
- }
-
-
- /*
- * ReadImageLine()
- *
- * If the current line is within the maximum image size,
- * Clear the error flags, and get back to the beginning of the line.
- * While we're not at the end of the line,
- * If the current column is within the maximum image size,
- * Get the pen number of the current pixel, and increment the column.
- * Update Plane0 and Plane1 (Plane0 has a zero wherever that plane
- * has at least one pixel that is zero; Plane1 has a 1 wherever
- * that plane has at least one pixel that is one).
- * If the bit mask has wrapped around, go on to the next image word.
- * For each 1 bit in the Pen color, add a 1 bit into the image data
- * Shift the image mask to the right.
- * Get the next pixel's pen color and skip any comments.
- * Skip trailing blanks (but not interior blanks).
- * Otherwise, indicate that the width is too large and skip to the
- * end of the line.
- * Update the current image size, if necessary.
- * Otherwise, indicate that the icon is too tall, and skip to the next line.
- */
-
- void ReadImageLine(y)
- short y;
- {
- short x = 0, w = 0;
- short d;
- UWORD mask = BIT(15);
- UBYTE Pen;
-
- if (y < MAXHEIGHT)
- {
- NoMaskError = TRUE; ErrorCount = 0;
- Reread();
- while (NextChar != '\n')
- {
- if (x < MAXWIDTH)
- {
- Pen = GetPen(NextChar); x++;
- Plane0 &= Pen; Plane1 |= Pen; d = 0;
- if (mask == 0) w++, mask = BIT(15);
- while (Pen)
- {
- if (Pen & 1) ImageData[w][y][d] |= mask;
- Pen >>= 1; d++;
- }
- mask >>= 1;
- GetNextChar(); SkipComments();
- if (NextChar == ' ')
- {
- SkipSpaces();
- if (NextChar != '\n') Reread();
- }
- } else {
- ReadFullLine();
- ShowError("Maximum Image Width of %d exceeded",MAXWIDTH);
- }
- }
- if (x > MaxWidth) MaxWidth = x, MaxWords = w+1;
- if (y+1 > MaxHeight) MaxHeight = y+1;
- if (MaxWidth > MAXWIDTH) MaxWidth = MAXWIDTH;
- } else {
- ReadFullLine();
- ShowError("Maxmimum Image Height of %d exceeded",MAXHEIGHT);
- }
- }
-
-
- /*
- * ReadIconFile()
- *
- * Get the rest of the line (it will be the file name to open)
- * Save the current file information.
- * Attempt to open the specified file.
- * If openned OK, then
- * Set the icon file flag,
- * Set the command list to the icon file command list and size.
- * Otherwise,
- * Put back the old file information,
- * Give an error about the icon file.
- */
-
- void ReadIconFile()
- {
- ReadFullLine();
- SaveOpenFile();
- if (OpenFile(Word))
- {
- IconFileOpen = TRUE;
- ComName = &IconCommand[0];
- ComOffset = COM_IMAGE;
- ComCount = MAXICONCOM;
- } else {
- RestoreFile();
- ShowError("Can't open Icon file '%s'",Word);
- }
- }
-
-
- /*
- * EndIconFile()
- *
- * Put back the old file information
- * Mark the file as closed, and restore the command list to the main list.
- */
-
- void EndIconFile()
- {
- RestoreFile();
- IconFileOpen = FALSE;
- ComName = &MainCommand[0];
- ComOffset = 0;
- ComCount = MAXMAINCOM;
- }
-